package com.mpgame.common.utils;

import com.google.common.net.HostAndPort;
import com.orbitz.consul.AgentClient;
import com.orbitz.consul.Consul;
import com.orbitz.consul.model.agent.ImmutableRegistration;
import com.orbitz.consul.model.agent.Registration;

import java.net.InetAddress;
import java.util.UUID;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class ConsulUtil {
        private static final String CONSUL_HOST = System.getProperty("consul.host",
            System.getenv().getOrDefault("CONSUL_HOST", "localhost"));
    private static final int CONSUL_PORT = Integer.getInteger("consul.port",
            Integer.parseInt(System.getenv().getOrDefault("CONSUL_PORT", "8500")));
    private static final Consul consul = Consul.builder()
            .withHostAndPort(HostAndPort.fromParts(CONSUL_HOST, CONSUL_PORT))
            .build();

    private static final AgentClient agentClient = consul.agentClient();
    private static String serviceId;
    private static final ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
    private static final int TTL_SECONDS = 30;
    private static volatile boolean agentRegistered = false;

    public static void registerAgentService(String serviceName, int port) {
        try {
            String address = InetAddress.getLocalHost().getHostAddress();
            serviceId = serviceName + "-" + address + "-" + port + "-" + UUID.randomUUID();
            Registration.RegCheck check = Registration.RegCheck.ttl(TTL_SECONDS);
            Registration registration = ImmutableRegistration.builder()
                    .id(serviceId)
                    .name(serviceName)
                    .address(address)
                    .port(port)
                    .addTags("grpc")
                    .check(check)
                    .build();
            agentClient.register(registration);
            agentRegistered = true;
            Log.info("Consul Agent 注册成功: " + serviceId + " -> " + address + ":" + port);
            startHeartbeat();
            Runtime.getRuntime().addShutdownHook(new Thread(ConsulUtil::deregisterAgentService));
        } catch (Exception e) {
            Log.err("Consul Agent 注册失败: " + e.getMessage());
        }
    }

    private static void startHeartbeat() {
        scheduler.scheduleAtFixedRate(() -> {
            if(!agentRegistered) return;
            try {
                agentClient.pass(serviceId);
            } catch (Exception e) {
                Log.err("Consul TTL 心跳失败: " + e.getMessage());
            }
        }, 0, TTL_SECONDS / 2, TimeUnit.SECONDS);
    }

    public static void deregisterAgentService() {
        if(!agentRegistered) return;
        try {
            agentClient.deregister(serviceId);
            Log.info("Consul Agent 注销成功: " + serviceId);
        } catch (Exception e) {
            Log.err("Consul Agent 注销失败: " + e.getMessage());
        } finally {
            agentRegistered = false;
            scheduler.shutdownNow();
        }
    }
}